package com.wangkang.eduservice.service.impl;
import com.wangkang.eduservice.entity.EduCourse;
import com.wangkang.eduservice.entity.EduCourseDescription;
import com.wangkang.eduservice.entity.query.EduCourseQuery;
import com.wangkang.eduservice.entity.vo.EduCourseInfoVo;
import com.wangkang.eduservice.entity.vo.EduCoursePublishVo;
import com.wangkang.eduservice.entity.vo.EduCourseWebVo;
import com.wangkang.eduservice.enums.EduResultCode;
import com.wangkang.eduservice.mapper.EduCourseMapper;
import com.wangkang.eduservice.service.*;
import com.wangkang.servicebase.exceptionhandler.exception.GuliException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author wangkang
 * @since 2022-04-13
 */
//用this或baseMapper来调用底层已定义好的方法，但仅能用baseMapper调用自己定义的方法。
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {
    @Autowired
    private  EduCourseDescriptionService courseDescriptionService;
    @Autowired
    private  EduVideoService videoService;
    @Autowired
    private  EduChapterService chapterService;

    public EduCourseServiceImpl(EduCourseDescriptionService courseDescriptionService, EduSubjectService subjectService, EduVideoService videoService, EduChapterService chapterService) {
        this.courseDescriptionService = courseDescriptionService;
        this.videoService = videoService;
        this.chapterService = chapterService;
    }

    /**
     * 保存课程信息
     *
     * @param courseInfoVo 课程信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveCourseInfo(EduCourseInfoVo courseInfoVo) {
        //1.向课程表添加课程基本信息
        //CourseInfoVo对象转换为eduCourse对象
        EduCourse eduCourse=new EduCourse();
        BeanUtils.copyProperties(courseInfoVo,eduCourse);
        int insert= baseMapper.insert(eduCourse);
        if(insert==0){
            //添加失败
            throw new GuliException(20001,"添加课程信息失败");

        }


//        EduSubject subject = subjectService.getById(courseInfoForm.getSubjectId());
//        subject = Optional.ofNullable(subject).orElseThrow(() -> GuliException.from(EduResultCode.DATA_NO_EXIST));
//
//        EduCourse course = new EduCourse();
//        BeanUtils.copyProperties(courseInfoForm,course);
//        course.setSubjectParentId(subject.getParentId());
//        boolean saveResult = this.save(course);
//        if(!saveResult){
//            //添加失败，提示用户
//            throw GuliException.from(EduResultCode.SAVE_ERROR);
//        }

        //获取添加之后的课程id
        String courseId = eduCourse.getId();

        //2.向课程简介表添加简介,此时baseMapper做不到直接添加了，需要用courseDescriptionService去写逻辑，用谁就注入谁，所以注入它。
        EduCourseDescription courseDescription = new EduCourseDescription();
        //设置courseDescription的id与description,
        //否则save时mybatis_plus自动生成的courseDescription的id是随机的，并不是course的id。
        courseDescription.setDescription(courseInfoVo.getDescription());
        courseDescription.setId(courseId);
        boolean saveCourseDescResult = courseDescriptionService.save(courseDescription);
        if (!saveCourseDescResult){
            throw GuliException.from(EduResultCode.SAVE_ERROR);
        }

        return courseId;
    }

    /**
     * 根据课程id 查询课程信息
     *
     * @param courseId 课程id
     * @return CourseInfoVo
     */
    @Override
    public EduCourseInfoVo getCourseInfoByCourseId(String courseId) {

        //1.查询课程信息
        EduCourse course = this.getById(courseId);
        EduCourseInfoVo courseInfoVo = new EduCourseInfoVo();

        BeanUtils.copyProperties(course,courseInfoVo);

        //2.查询课程描述信息
        //courseDescription的id为courseId，在该方法中已知，故不用再设置。
        EduCourseDescription courseDescription = courseDescriptionService.getById(courseId);
        courseInfoVo.setDescription(courseDescription.getDescription());
        return courseInfoVo;
    }

    /**
     * 修改课程信息
     *
     * @param courseInfoVo
     */
    @Override
    public void updateCourse(EduCourseInfoVo courseInfoVo) {
        //1.修改课程表
        EduCourse course = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo,course);
//        boolean updateResult = updateById(course);
//        if(!updateResult){
//            throw GuliException.from(EduResultCode.UPDATE_ERROR);
//        }
          int update=baseMapper.updateById(course);
          if(update==0){

              throw GuliException.from(EduResultCode.UPDATE_ERROR);
          }



        //2.修改描述表
        //设置courseDescription的id与description。
        //EduCourseDescription courseDescription = new EduCourseDescription(courseInfoForm.getId(),courseInfoForm.getDescription());
        EduCourseDescription courseDescription = new EduCourseDescription();
        //设置courseDescription的id与description。
        courseDescription.setDescription(courseInfoVo.getDescription());
        courseDescription.setId(courseInfoVo.getId());
        boolean updateDescResult = courseDescriptionService.updateById(courseDescription);

        if (!updateDescResult){
            throw GuliException.from(EduResultCode.UPDATE_ERROR);
        }

    }

    /**
     * 根据课程id查询课程确认信息
     *
     * @param id 课程id
     * @return CoursePublishVo
     */
    @Override
    public EduCoursePublishVo publishCourseInfo(String id) {

        EduCoursePublishVo publishCourseInfo = this.baseMapper.getPublishCourseInfo(id);
        return publishCourseInfo;
    }

    /**
     * 根据课程id删除课程信息
     * 由于video表中有course的id与chapter的id，
     * chapter表中有course的id，这些外键约束
     * 所以先删小节，再删章节，最后删课程本身。
     * description表中无course的外键约束，先删后删均可。
     *
     * @param courseId 课程id
     */
    @Override
    public void deleteCourse(String courseId) {
        //1.根据课程id删除小节(deleteVideoByCourseId方法中远程调用deleteBatch方法)
        videoService.deleteVideoByCourseId(courseId);

        //2.根据课程id删除章节
        chapterService.deleteChapterByCourseId(courseId);

        //3.根据课程id删除描述
        boolean removeDesc = courseDescriptionService.removeById(courseId);
        if(!removeDesc){
            throw GuliException.from(EduResultCode.DELETE_ERROR);
        }

        //4.根据课程id删除课程本身
        boolean removeCourseResult = this.removeById(courseId);

        if(!removeCourseResult){
            throw GuliException.from(EduResultCode.DELETE_ERROR);
        }


    }

    /**
     * 条件查询带分页查询课程
     *
     * @param coursePage  分页对象
     * @param courseQuery 条件查询
     * @return 查询结果
     */
    @Override
    public Map<String, Object> getCourseFrontList(Page<EduCourse> coursePage, EduCourseQuery courseQuery) {

        LambdaQueryWrapper<EduCourse> courseWrapper = new LambdaQueryWrapper<>();
        //若一级分类不为空
        courseWrapper.eq(StringUtils.isNotBlank(courseQuery.getSubjectParentId()),EduCourse::getSubjectParentId,courseQuery.getSubjectParentId());
        //若二级分类不为空
        courseWrapper.eq(StringUtils.isNotBlank(courseQuery.getSubjectId()),EduCourse::getSubjectId,courseQuery.getSubjectId());

        //关注度不为空
        courseWrapper.orderByDesc(StringUtils.isNotBlank(courseQuery.getBuyCountSort()),EduCourse::getBuyCount);

        //最新不为空
        courseWrapper.orderByDesc(StringUtils.isNotBlank(courseQuery.getGmtCreateSort()),EduCourse::getGmtCreate);

        //价格不为空
        courseWrapper.orderByDesc(StringUtils.isNotBlank(courseQuery.getPriceSort()),EduCourse::getPrice);

        this.page(coursePage, courseWrapper);
        //数据列表
        List<EduCourse> records = coursePage.getRecords();
        //当前页码
        long current = coursePage.getCurrent();
        //总页数
        long pages = coursePage.getPages();
        //每页容量
        long size = coursePage.getSize();
        //总记录数
        long total = coursePage.getTotal();
        //下一页
        boolean hasNext = coursePage.hasNext();
        //上一页
        boolean hasPrevious = coursePage.hasPrevious();

        //把分页数据获取出来，放到map集合
        Map<String, Object> map = Maps.newHashMap();
        map.put("items", records);
        map.put("current", current);
        map.put("pages", pages);
        map.put("size", size);
        map.put("total", total);
        map.put("hasNext", hasNext);
        map.put("hasPrevious", hasPrevious);

        return map;
    }

    /**
     * 查询课程基本信息
     *
     * @param courseId
     * @return
     */
    @Override
    public EduCourseWebVo getBaseCourseInfo(String courseId) {
        return this.baseMapper.getBaseCourseInfo(courseId);
    }
}